package com.lyl.novel.third.excel.listener;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.lyl.example.common.exception.BizException;
import com.lyl.novel.third.excel.entity.TaskExcel;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Mr.Luo
 * @date 2022-08-24 16:34
 * @desc 定时任务监听器
 */
@Slf4j
public class TaskExcelListener implements ReadListener<TaskExcel> {

    private static final Set<String> EXCEL_HEAD_SET;
    private List<TaskExcel> cachedDataList = ListUtils.newArrayList();

    static {
        EXCEL_HEAD_SET = Arrays.stream(TaskExcel.class.getDeclaredFields())
                .filter(field -> field.isAnnotationPresent(ExcelProperty.class))
                .map(field -> {
                    String[] value = field.getAnnotation(ExcelProperty.class).value();
                    return ObjectUtil.isNotEmpty(value) ? value[0] : null;
                })
                .filter(ObjectUtil::isNotNull)
                .collect(Collectors.toSet());
    }

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        //校验上传文件模板是否对应
        Set<String> headSet = headMap.values().stream()
                .map(CellData::getStringValue)
                .collect(Collectors.toSet());
        Assert.isTrue(EXCEL_HEAD_SET.size() == headSet.size(), () -> new BizException("文件内容或者模板错误"));
        Assert.isTrue(CollUtil.subtract(EXCEL_HEAD_SET, headSet).isEmpty(), () -> new BizException("文件内容或者模板错误"));
    }

    @Override
    public void invoke(TaskExcel taskExcel, AnalysisContext analysisContext) {
        log.info("解析到一条数据:{}", JSONUtil.toJsonStr(taskExcel));
        cachedDataList.add(taskExcel);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //保存数据到数据库中
        int size = cachedDataList.size();
        log.info("保存到数据库中{}条数据", size);
    }
}
